/*
	   _           _      _           _     _ 
	  (_)         | |    | |         (_)   | |
	   _ _   _ ___| |_ __| |_ __ ___  _  __| |
	  | | | | / __| __/ _` | '__/ _ \| |/ _` |
	  | | |_| \__ \ || (_| | | | (_) | | (_| |
	  | |\__,_|___/\__\__,_|_|  \___/|_|\__,_|
	 _/ |                                     
	|__/ 
	
	Copyright 2013 Caspar Isemer and and Eva Krueger, http://justdroid.org
	
	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at
	
		http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License. 
*/

package org.justdroid.justdroid;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.ContentProviderOperation;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;
import android.provider.ContactsContract.RawContacts;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ContactsOtherOptions extends JustDroidActivity {
	
	/** Declare variables and UI elements **/
	private TextView contactName;
	private Button btnDelete, btnCopyToSD, btnImport, btnExport;
	private String id, contactNumber;
	private Handler handler;
	private final int EXPORTONECONTACT = 1;
	private final int EXPORTALLCONTACTS = 2;
	
	private void attachKeyListener(Button button, final int buttonFlag) {
		button.setOnKeyListener(new OnKeyListener() {
			
			@Override
			public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
				if(keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
					switch(keyCode) {
					case KeyEvent.KEYCODE_DPAD_CENTER:
					case KeyEvent.KEYCODE_ENTER:
						switch(buttonFlag) {
							case 1:
								confirmDelete("Are you sure you want to delete the contact?");
								break;
							case 2:
								copyToSDcard();
								break;
							case 3:
								export();
								break;
							case 4:
								importContact();
								break;
						}
						break;
					}
				}
				return false;
			}
		});
	}
	
	private void importContact() {
		final Intent intent = new Intent(Intent.ACTION_VIEW);
		final File[] files = new File(Environment.getExternalStorageDirectory() + File.separator + getResources().getString(R.string.appName)).listFiles();
		if(files == null) {
			Toast.makeText(getApplicationContext(), getResources().getString(R.string.filesabsent), Toast.LENGTH_SHORT).show();
			if(Utils.isAccessibilityEnabled(getApplicationContext()))
				TTS.speak(getResources().getString(R.string.filesabsent));
		}
		else {
			Toast.makeText(getApplicationContext(), getResources().getString(R.string.importing), Toast.LENGTH_SHORT).show();
			Runnable runnable = new Runnable() {
				
				@Override
				public void run() {
					if(Utils.isAccessibilityEnabled(getApplicationContext()))
						TTS.speak(getResources().getString(R.string.importing));
					for(int i=0; i< files.length; i++) {
						if(files[i].getName().endsWith(".vcf")) {
							try {
								intent.setDataAndType(Uri.fromFile(new File(files[i].getAbsolutePath())), "text/x-vcard");
								startActivity(intent);
							}
							catch(Exception e) {
								TTS.speak(getResources().getString(R.string.importfailed));
							}
						}
					}
					TTS.speak(getResources().getString(R.string.importsuccess));
				}
			};
			new Thread(runnable).start();
		}
	}
	
	private void export() {
		if(TTS.isSpeaking())
			TTS.stop();
			if(getSDcardStatus()) {
				if(TTS.isSpeaking())
					TTS.stop();
				if(Utils.isAccessibilityEnabled(getApplicationContext()))
					TTS.speak(getResources().getString(R.string.exporting));
				Toast.makeText(getApplicationContext(), getResources().getString(R.string.exporting), Toast.LENGTH_SHORT).show();
				Runnable runnable = new Runnable() {
				
				@Override
				public void run() {
					Bundle bundle = new Bundle();
					Message message = new Message();
					Cursor cursor = getContentResolver().query(Data.CONTENT_URI, null, 
							null, null, null);
					if(getVCF(cursor)) {
						bundle.putBoolean("success", true);
					}
					else {
						bundle.putBoolean("success", false);
					}
					bundle.putInt("type", EXPORTALLCONTACTS);
					message.setData(bundle);
					handler.sendMessage(message);
				}
			};
			new Thread(runnable).start();
		}
	}
	
	private void copyToSDcard() {
		if(getSDcardStatus()) {
			Runnable runnable = new Runnable() {
				
				@Override
				public void run() {
					Bundle bundle = new Bundle();
					Message message = new Message();
					Cursor cursor = getContentResolver().query(Data.CONTENT_URI, null, 
							Data.CONTACT_ID +" = ?", new String[]{ContactsOtherOptions.this.id}, null);
					if(getVCF(cursor)) {
						bundle.putBoolean("success", true);
					}
					else {
						bundle.putBoolean("success", false);
					}
					bundle.putInt("type", EXPORTONECONTACT);
					message.setData(bundle);
					handler.sendMessage(message);
				}
			};
			new Thread(runnable).start();
		}
	}
	private void confirmDelete(String message)
	 {
		TTS.stop();
		if(Utils.isAccessibilityEnabled(getApplicationContext()))
			giveFeedback(message);
	    AlertDialog confirmBox =new AlertDialog.Builder(this) 
	        //set message, title, and icon
	        .setTitle(getResources().getString(R.string.btnTextMsgsDelete)) 
	        .setMessage(message)
	        .setPositiveButton("Yes", new DialogInterface.OnClickListener() {

	            public void onClick(DialogInterface dialog, int whichButton) { 
	            	if(deleteContact(ContactsOtherOptions.this.contactNumber)) {
	            		if(Utils.isAccessibilityEnabled(getApplicationContext()))
	            			TTS.speak(getResources().getString(R.string.deletesuccess));
						Toast.makeText(getApplicationContext(), getResources().getString(R.string.deletesuccess), Toast.LENGTH_SHORT).show();
						//go to ContactsApp
						finish();
						Intent intent = new Intent(getApplicationContext(), ContactsApp.class);
						intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
						startActivity(intent);
					}
					else
					{
						if(Utils.isAccessibilityEnabled(getApplicationContext()))
							TTS.speak(getResources().getString(R.string.deletefailure));
						Toast.makeText(getApplicationContext(), getResources().getString(R.string.deletefailure), Toast.LENGTH_SHORT).show();
					}
	                dialog.dismiss();
	            }   

	        })
	        
	        .setNegativeButton("No", new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int which) {

	                dialog.dismiss();

	            }
	        })
	        .create();
	        confirmBox.show();
	}
	
	/** Function to delete contact based on the number passed as an argument 
	 * @return **/
	boolean deleteContact(String number) {
		ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        String[] args = new String[] { String.valueOf(getContactID(
                getContentResolver(), number)) };
 
        ops.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
                .withSelection(RawContacts.CONTACT_ID + "=?", args).build());
        try {
            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (RemoteException e) {
            e.printStackTrace();
            return false;
        } catch (OperationApplicationException e) {
            e.printStackTrace();
            return false;
        }
        return true;
	}
	
	/** Function check if SD card is usable **/
	boolean getSDcardStatus() {
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
			if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
				if(TTS.isSpeaking())
					TTS.stop();
				if(Utils.isAccessibilityEnabled(getApplicationContext()))
					TTS.speak(getResources().getString(R.string.mediareadonly));
				Toast.makeText(getApplicationContext(), getResources().getString(R.string.mediareadonly), Toast.LENGTH_SHORT).show();
				return false;
			}
			else {
				return true;
			}
		}
		if(TTS.isSpeaking())
			TTS.stop();
		if(Utils.isAccessibilityEnabled(getApplicationContext()))
			TTS.speak(getResources().getString(R.string.mediaunmounted));
		Toast.makeText(getApplicationContext(), getResources().getString(R.string.mediaunmounted), Toast.LENGTH_SHORT).show();
		return false;
	}
	
	long getContactID(ContentResolver contactHelper,
            String number) {
        Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
                Uri.encode(number));
 
        String[] projection = { PhoneLookup._ID };
        Cursor cursor = null;
 
        try {
            cursor = contactHelper.query(contactUri, projection, null, null,
                    null);
 
            if (cursor.moveToFirst()) {
                int personID = cursor.getColumnIndex(PhoneLookup._ID);
                return cursor.getLong(personID);
            }
 
            return -1;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
                cursor = null;
            }
        }
 
        return -1;
    }
	
	/** Function to export one contact to SD card **/
	public boolean getVCF(Cursor cursor) {
	 while(cursor.moveToNext()) {
		 String lookupKey =  cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
	     Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);

	    AssetFileDescriptor fd;
	     try 
	     {
	         fd = getContentResolver().openAssetFileDescriptor(uri, "r");
	         FileInputStream fis = fd.createInputStream();
	         byte[] buf = new byte[(int) fd.getDeclaredLength()];
	         fis.read(buf);
	         String VCard = new String(buf);
	         String vfile = cursor.getString(cursor.getColumnIndex("display_name")).replaceAll("[^a-zA-Z0-9_]", "") + "_" + cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)) + ".vcf";
	         String path = Environment.getExternalStorageDirectory().toString() + File.separator + getResources().getString(R.string.appName);
	         File directory = new File(path);
	         if(!directory.exists())
	        	 directory.mkdirs();
	         File outputFile = new File(path, vfile);
	         @SuppressWarnings("resource")
			 FileOutputStream mFileOutputStream = new FileOutputStream(outputFile);
	         mFileOutputStream.write(VCard.toString().getBytes());
	     }
	     catch (Exception e) {
	         e.printStackTrace();
	         return false;
	     }
	 }
	 return true;
	}
	
	/** Create the Contact Details menu activity **/
	@SuppressLint("HandlerLeak")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		setContentView(R.layout.contactsotheroptions);
		super.onCreate(savedInstanceState);
		
		/** get UI elements **/
		contactName = (TextView) findViewById(R.id.txtContactsName);
		btnDelete = (Button) findViewById(R.id.btnDelete);
		btnCopyToSD = (Button) findViewById(R.id.btnCopyToSD);
		btnImport = (Button) findViewById(R.id.btnImportFromSD);
		btnExport = (Button) findViewById(R.id.btnExportToSD);
		
		
		/** get the details of the contact from the number **/
		if(getIntent().getExtras() != null) {
			this.id = getIntent().getExtras().getString("id");
		}
		
		HashMap<String, ArrayList<String>> contactDetails = new ContactManager(getApplicationContext()).getDetailsFromNumber(this.id);
		
		contactName.setText(contactDetails.get("name").get(0));
		
		/*contactName.setOnTouchListener(new OnTouchListener() {
			
			@Override
			public boolean onTouch(View view, MotionEvent arg1) {
				giveFeedback(((TextView)view).getText().toString());
				return false;
			}
		});*/
		
		contactName.setOnFocusChangeListener(new OnFocusChangeListener() {
			
			@Override
			public void onFocusChange(View view, boolean hasFocus) {
				if(hasFocus) {
					giveFeedback(((TextView)view).getText().toString());
				}
			}
		});
		
		attachListener(btnDelete);
		attachListener(btnCopyToSD);
		attachListener(btnImport);
		attachListener(btnExport);
		
		attachKeyListener(btnDelete, 1);
		
		btnDelete.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				confirmDelete("Are you sure you want to delete the contact?");
			}
		});
		
		attachKeyListener(btnCopyToSD, 2);
		
		btnCopyToSD.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				copyToSDcard();
			}
		});
		
		btnExport.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View view) {
				export();
			}
		});
		
		attachKeyListener(btnExport, 3);
		
		btnImport.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View view) {
				importContact();
			}
		});
		
		attachKeyListener(btnImport, 4);
		
		// The OnClick code below for btnContactsNumber1, btnContactsNumber1, btnContactsNumber1
		// is just dummy code; it should actually receive all the numbers from the contact selected
		// via ContactsApp.java, display all numbers each as a separate button and upon clicking
		// calls the selected number	
		
		/** Dial respective phone number, depending on which button is pressed **/
		//dialNumberOnButtonClick(R.id.btnContactsNumber1, "+491771111111");
		//dialNumberOnButtonClick(R.id.btnContactsNumber2, "+49401111111");
		//dialNumberOnButtonClick(R.id.btnContactsNumber3, "+4940808171111");
				
		handler = new Handler() {
			public void handleMessage(Message message) {
				if(message.getData().getInt("type") == EXPORTONECONTACT) {
					if(message.getData().getBoolean("success") == true) {
						TTS.stop();
						if(Utils.isAccessibilityEnabled(getApplicationContext()))
							TTS.speak(getResources().getString(R.string.copycontactsuccess));
						Toast.makeText(getApplicationContext(), getResources().getString(R.string.copycontactsuccess), Toast.LENGTH_SHORT).show();
					}
					else {
						TTS.stop();
						if(Utils.isAccessibilityEnabled(getApplicationContext()))
							TTS.speak(getResources().getString(R.string.copycontactfailure));
						Toast.makeText(getApplicationContext(), getResources().getString(R.string.copycontactfailure), Toast.LENGTH_SHORT).show();
					}
				}
				else if(message.getData().getInt("type") == EXPORTALLCONTACTS) {
					if(message.getData().getBoolean("success") == true) {
						TTS.stop();
						if(Utils.isAccessibilityEnabled(getApplicationContext()))
							TTS.speak(getResources().getString(R.string.copyallcontactssuccess));
						Toast.makeText(getApplicationContext(), getResources().getString(R.string.copyallcontactssuccess), Toast.LENGTH_SHORT).show();
					}
					else {
						TTS.stop();
						if(Utils.isAccessibilityEnabled(getApplicationContext()))
							TTS.speak(getResources().getString(R.string.copyallcontactsfailure));
						Toast.makeText(getApplicationContext(), getResources().getString(R.string.copyallcontactsfailure), Toast.LENGTH_SHORT).show();
					}
				}
			}
		};
				
		/** Put most everything before here **/
	}
	
	@Override
	public void onResume() {
		super.onResume();
		//get the root layout
		LinearLayout layout = (LinearLayout) findViewById(R.id.contactsotheroptions);
		Utils.applyFontColorChanges(getApplicationContext(), layout);  Utils.applyFontSizeChanges(getApplicationContext(), layout);  Utils.applyFontTypeChanges(getApplicationContext(), layout);
	}
}
